const Imap = require('imap');
const simpleParser = require('mailparser').simpleParser;
const nodemailer = require('nodemailer');
const fs = require('fs');
const path = require('path');

class EmailService {
  constructor(username, password) {
    this.username = username;
    this.password = password;
    this.imapConfig = {
      user: username,
      password: password,
      host: 'imaphz.qiye.163.com',
      port: 993,
      tls: true,
    };
    this.smtpConfig = {
      host: 'smtphz.qiye.163.com',
      port: 465,
      secure: true,
      auth: {
        user: username,
        pass: password,
      },
    };
  }

  async fetchEmails(folderName = 'INBOX') {
    return new Promise((resolve, reject) => {
      const imap = new Imap(this.imapConfig);
      const emails = [];

      imap.once('ready', () => {
        imap.openBox(folderName, false, (err, box) => {
          if (err) reject(err);
          const f = imap.seq.fetch('1:10', {
            bodies: ['HEADER', 'TEXT'],
            markSeen: false,
          });
          f.on('message', (msg) => {
            msg.on('body', (stream, info) => {
              simpleParser(stream, (err, parsed) => {
                if (err) {
                  console.error('Error parsing email:', err);
                  return;
                }
                emails.push({
                  id: parsed.messageId || 'Unknown ID',
                  from: parsed.from ? parsed.from.text : 'Unknown Sender',
                  subject: parsed.subject || 'No Subject',
                  date: parsed.date || new Date(),
                  text: parsed.text || parsed.textAsHtml || 'No Content'
                });
              });
            });
          });
          f.once('error', (err) => {
            reject(err);
          });
          f.once('end', () => {
            imap.end();
            resolve(emails);
          });
        });
      });
      imap.once('error', (err) => {
        reject(err);
      });
      imap.connect();
    });
  }

  async sendEmail(to, subject, text, attachments = []) {
    const transporter = nodemailer.createTransport(this.smtpConfig);
    const mailOptions = {
      from: this.username,
      to: to,
      subject: subject,
      text: text,
      attachments: attachments.map(filePath => ({
        filename: path.basename(filePath),
        path: filePath
      }))
    };
    return transporter.sendMail(mailOptions);
  }

  async markEmail(messageId, flag) {
    return new Promise((resolve, reject) => {
      const imap = new Imap(this.imapConfig);
      imap.once('ready', () => {
        imap.openBox('INBOX', false, (err, box) => {
          if (err) reject(err);
          imap.addFlags(messageId, flag, (err) => {
            if (err) reject(err);
            imap.end();
            resolve();
          });
        });
      });
      imap.once('error', (err) => {
        reject(err);
      });
      imap.connect();
    });
  }

  async moveEmail(messageId, destination) {
    return new Promise((resolve, reject) => {
      const imap = new Imap(this.imapConfig);
      imap.once('ready', () => {
        imap.openBox('INBOX', false, (err, box) => {
          if (err) reject(err);
          imap.move(messageId, destination, (err) => {
            if (err) reject(err);
            imap.end();
            resolve();
          });
        });
      });
      imap.once('error', (err) => {
        reject(err);
      });
      imap.connect();
    });
  }  
}

module.exports = EmailService;